﻿using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using TigerController.Comparison;

namespace TigerController.Comparison
{
    public class DrawingSystem
    {
        private readonly Canvas rootCanvas;
        private readonly KinectSensor sensor;
        public DrawingSystem(
            KinectSensor kinectSensor,
            Canvas root
            )
        {
            rootCanvas = root;
            sensor = kinectSensor;
        }
        void GetCoordinates(JointType jointType, IEnumerable<Joint> joints, out float x, out float y)
        {
            var joint = joints.First(j => j.JointType == jointType);
            
            Vector2 vector2 = Tools.Convert(sensor, joint.Position);

            x = (float)(vector2.X * rootCanvas.ActualWidth);
            y = (float)(vector2.Y * rootCanvas.ActualHeight);
        }

        void Plot(JointType centerID, IEnumerable<Joint> joints, Color color)
        {
            float centerX;
            float centerY;

            GetCoordinates(centerID, joints, out centerX, out centerY);

            const double diameter = 8;

            Ellipse ellipse = new Ellipse
            {
                Width = diameter,
                Height = diameter,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                StrokeThickness = 4.0,
                Stroke = new SolidColorBrush(color),
                StrokeLineJoin = PenLineJoin.Round
            };

            Canvas.SetLeft(ellipse, centerX - ellipse.Width / 2);
            Canvas.SetTop(ellipse, centerY - ellipse.Height / 2);

            rootCanvas.Children.Add(ellipse);
        }

        void Plot(JointType centerID, JointType baseID, JointCollection joints, Color color)
        {
            float centerX;
            float centerY;

            GetCoordinates(centerID, joints, out centerX, out centerY);

            float baseX;
            float baseY;

            GetCoordinates(baseID, joints, out baseX, out baseY);

            double diameter = Math.Abs(baseY - centerY);

            Ellipse ellipse = new Ellipse
            {
                Width = diameter,
                Height = diameter,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                StrokeThickness = 4.0,
                Stroke = new SolidColorBrush(color),
                StrokeLineJoin = PenLineJoin.Round
            };

            Canvas.SetLeft(ellipse, centerX - ellipse.Width / 2);
            Canvas.SetTop(ellipse, centerY - ellipse.Height / 2);

            rootCanvas.Children.Add(ellipse);
        }

        void Trace(JointType sourceID, JointType destinationID, JointCollection joints, Color color)
        {
            float sourceX;
            float sourceY;

            GetCoordinates(sourceID, joints, out sourceX, out sourceY);

            float destinationX;
            float destinationY;

            GetCoordinates(destinationID, joints, out destinationX, out destinationY);

            Line line = new Line
            {
                X1 = sourceX,
                Y1 = sourceY,
                X2 = destinationX,
                Y2 = destinationY,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                StrokeThickness = 4.0,
                Stroke = new SolidColorBrush(Colors.Green),
                StrokeLineJoin = PenLineJoin.Round
            };


            rootCanvas.Children.Add(line);
        }
        public void Render(
            ScoreOfSpecificJoint[] scoreOfSpecificJoints,
            Skeleton currentSkeleton,
            Canvas canvas)
        {
            ColorOfSpecificJoint[] colorOfSpecificJoints
                = new ColorOfSpecificJoint[scoreOfSpecificJoints.GetUpperBound(0)];
            for (Int32 index = 0; index < scoreOfSpecificJoints.GetUpperBound(0); index++)
            {
                colorOfSpecificJoints[index] = scoreOfSpecificJoints[index];
            }
            rootCanvas.Children.Clear();
            Plot(JointType.HandLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.HandLeft].Color);
            Trace(JointType.HandLeft, JointType.WristLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.HandLeft].Color);

            Plot(JointType.WristLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.WristLeft].Color);
            Trace(JointType.WristLeft, JointType.ElbowLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.WristLeft].Color);

            Plot(JointType.ElbowLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.ElbowLeft].Color);
            Trace(JointType.ElbowLeft, JointType.ShoulderLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.ElbowLeft].Color);

            Plot(JointType.ShoulderLeft, currentSkeleton.Joints, Colors.Green);
            Trace(JointType.ShoulderLeft, JointType.ShoulderCenter, currentSkeleton.Joints, Colors.Green);
            Plot(JointType.ShoulderCenter, currentSkeleton.Joints, Colors.Green);
            Trace(JointType.ShoulderCenter, JointType.Head, currentSkeleton.Joints, Colors.Green);
            Plot(JointType.Head, JointType.ShoulderCenter, currentSkeleton.Joints, Colors.Green);
            Trace(JointType.ShoulderCenter, JointType.ShoulderRight, currentSkeleton.Joints, Colors.Green);
            Plot(JointType.ShoulderRight, currentSkeleton.Joints, Colors.Green);

            Plot(JointType.HandRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.HandRight].Color);
            Trace(JointType.WristRight, JointType.HandRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.HandRight].Color);

            Plot(JointType.WristRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.WristRight].Color);
            Trace(JointType.ElbowRight, JointType.WristRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.WristRight].Color);

            Plot(JointType.ElbowRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.ElbowRight].Color);
            Trace(JointType.ShoulderRight, JointType.ElbowRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.ElbowRight].Color);

            Trace(JointType.ShoulderCenter, JointType.Spine, currentSkeleton.Joints, Colors.Green);
            Plot(JointType.Spine, currentSkeleton.Joints, Colors.Green);
            Trace(JointType.Spine, JointType.HipCenter, currentSkeleton.Joints, Colors.Green);
            Plot(JointType.HipCenter, currentSkeleton.Joints, Colors.Green);
            Trace(JointType.HipCenter, JointType.HipLeft, currentSkeleton.Joints, Colors.Green);
            Plot(JointType.HipLeft, currentSkeleton.Joints, Colors.Green);

            Plot(JointType.FootLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.FootLeft].Color);
            Trace(JointType.AnkleLeft, JointType.FootLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.FootLeft].Color);

            Plot(JointType.AnkleLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.AnkleLeft].Color);
            Trace(JointType.KneeLeft, JointType.AnkleLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.AnkleLeft].Color);

            Plot(JointType.KneeLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.KneeLeft].Color);
            Trace(JointType.HipLeft, JointType.KneeLeft, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.KneeLeft].Color);

            Trace(JointType.HipCenter, JointType.HipRight, currentSkeleton.Joints, Colors.Green);
            Plot(JointType.HipRight, currentSkeleton.Joints, Colors.Green);

            Plot(JointType.FootRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.FootRight].Color);
            Trace(JointType.AnkleRight, JointType.FootRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.FootRight].Color);

            Plot(JointType.AnkleRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.AnkleRight].Color);
            Trace(JointType.KneeRight, JointType.AnkleRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.AnkleRight].Color);

            Plot(JointType.KneeRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.KneeRight].Color);
            Trace(JointType.HipRight, JointType.KneeRight, currentSkeleton.Joints, colorOfSpecificJoints[(Int32)JointType.KneeRight].Color);
        }
    }
}
